# 1 "semaforo.c"
# 1 "/home/diego/sodium/kernel//"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "semaforo.c"
# 1 "../include/kernel/semaforo.h" 1
# 20 "../include/kernel/semaforo.h"
typedef struct
{
 int inicializado;
 int valor;
 unsigned long int head;
 unsigned long int tail;

 unsigned long int procesosEnCola;

 unsigned long int cola[5];
 unsigned long int pshared;
}semaforo;





typedef struct
{
 int sem_id;
}sem_t;





typedef struct{
 int pshared;
 unsigned int value;
} sem_init_params;


void vFnEncolarProceso(semaforo *sem, unsigned long int uliId);


void vFnInicializaCola(unsigned long int *cola);


int iFnHayProcesoEnEspera(semaforo *sem);


unsigned long int uliFnDesencolarProceso(semaforo *sem);


void vFnInicializarSemaforos();
# 77 "../include/kernel/semaforo.h"
int iFnSemInit(sem_t *sem, int pshared, unsigned int value);
# 86 "../include/kernel/semaforo.h"
int iFnSemClose(sem_t *sem);
# 106 "../include/kernel/semaforo.h"
int iFnSemWait(sem_t *sem);
# 116 "../include/kernel/semaforo.h"
int iFnSemPost(sem_t *sem);

int validaExistenciaSemaforo(sem_t *sem);


int agregarSemaforoAlSistema(int pshared, unsigned int value);

void vFnVerSemaforos();
# 2 "semaforo.c" 2
# 1 "../include/kernel/definiciones.h" 1
# 14 "../include/kernel/definiciones.h"
# 1 "../include/usr/tipos.h" 1
# 15 "../include/usr/tipos.h"
typedef unsigned int dword;
typedef unsigned short word;
typedef unsigned char byte;

typedef unsigned char u8;
typedef signed char s8;
typedef unsigned short u16;
typedef signed short s16;
typedef unsigned int u32;
typedef signed int s32;


typedef struct _u80 { unsigned int word[20]; } u80;
# 15 "../include/kernel/definiciones.h" 2
# 62 "../include/kernel/definiciones.h"
char stArgAux[128];
# 3 "semaforo.c" 2
# 1 "../include/kernel/pcb.h" 1







# 1 "../include/kernel/shm.h" 1
# 18 "../include/kernel/shm.h"
typedef unsigned int size_t;
typedef int key_t;
typedef int bool;


typedef struct _stuMemoriasAtachadas_
{
 bool utilizada;
 int posicionEnShMem;
 int posicionEnAttach;
}stuMemoriasAtachadas;


typedef struct _attach_
{
 int pid;
 void * ptrShAddr;

}attach;


typedef struct _shMem_
{
 key_t key;
 unsigned long int tamanio;
 attach procAtt[5];
 bool declarada;
}shMem;

shMem memoriasCompartidas[5];




int iFnShmGet(key_t key, size_t size);


int iFnShmAt(int shmid, void * shmAddr);


int iFnShmDt(int shmid);

int iFnShmDtProc(int shmid, unsigned int uiPid);
int iFnShmDtAllProc(unsigned int uiPid);

unsigned long ulFnMaxDirShmProc(unsigned int uiPid);

void vFnInicializarShms();
void vFnVerShm();




void vFnCopiarVariablesCompartidas();



void vFnCopiarVariable(void * dest, void * src, size_t tamanio);
# 9 "../include/kernel/pcb.h" 2
# 1 "../include/kernel/tiempo.h" 1
# 53 "../include/kernel/tiempo.h"
typedef unsigned long int time_t;
typedef unsigned long int clock_t;





typedef struct{

        clock_t tms_utime;


        clock_t tms_stime;


        clock_t tms_cutime;


        clock_t tms_cstime;
} tms;





typedef struct{

        int tz_minuteswest;


        int tz_dsttime;
} timezone;





typedef struct{

        unsigned long int tv_sec;


        unsigned long int tv_usec;
} timeval;





typedef struct{

        timeval it_interval;


        timeval it_value;
} itimerval;





typedef struct{

        int modes;


 long offset;


 long freq;


 long maxerror;


 long esterror;


 int status;


 long constant;


 long precision;


 long tolerance;


 timeval time;


 long tick;
} timex;





typedef struct{

        long int tv_sec;


        long int tv_nsec;
} timespec;
# 10 "../include/kernel/pcb.h" 2
# 27 "../include/kernel/pcb.h"
typedef struct {
 unsigned char ident[16];
 unsigned short type;
 unsigned short machine;
 unsigned int version;
 unsigned int entry;
 unsigned int phoff;
 unsigned int sphoff;
 unsigned int flags;
 unsigned short ehsize;
 unsigned short phentsize;
 unsigned short phnum;
 unsigned short shentsize;
 unsigned short shnum;
 unsigned short shstrndx;
} elfHeader;

typedef struct {
 unsigned int name;
 unsigned int type;
 unsigned int flags;
 unsigned int addr;
 unsigned int offset;
 unsigned int size;
 unsigned int link;
 unsigned int info;
 unsigned int addralign;
 unsigned int entsize;
}SHeader;

typedef struct {
        unsigned int type;
 unsigned int offset;
 unsigned int vaddr;
        unsigned int paddr;
        unsigned int filesz;
        unsigned int memsz;
        unsigned int flags;
        unsigned int align;
} PHeader;






typedef struct {
   elfHeader elfHeaderData;
   SHeader SHeaderData;
   PHeader PHeaderData;
   unsigned char ucbuffer[4];
} stuHeaderELF;





typedef struct {
   int iEstado;
   long int liTamanio;
} stuEsperarMemoria;
# 96 "../include/kernel/pcb.h"
typedef struct _stuPCB_{
  unsigned long int ulId;
  unsigned int uiIndiceGDT_CS;
  unsigned int uiIndiceGDT_DS;
  unsigned int uiIndiceGDT_TSS;
  unsigned int uiIndiceGDT_SS0;
  void (* vFnFuncion) ();

  unsigned long ulParentId;
  unsigned long ulUsuarioId;
  int iPrioridad;
  int iEstado;
  unsigned long lNHijos;
  int iExitStatus;
  unsigned long ulLugarTSS;
  char stNombre[25];
  unsigned int uiTamProc;
  struct stuTablaPagina * pstuTablaPaginacion;
  unsigned int uiDirBase,

        uiLimite;
  stuMemoriasAtachadas memoriasAtachadas[5];


  unsigned long ulTiempoEspera;
  unsigned long ulTiempoServicio;



  struct stuPCB* pstuPcbSiguiente;

  tms stuTmsTiemposProceso;

  itimerval timers[3];

  long lNanosleep;

  unsigned int *puRestoDelNanosleep;

    long lPidTracer;

    unsigned int uiTamanioTexto;
    unsigned int uiTamanioDatosInicializados;
    unsigned int uiTamanioStack;

    unsigned int uiTamanioOverhead;

    unsigned int uiEsperaTeclado;

    stuHeaderELF stuCabeceraELF;
    int iModoParticion;
    stuEsperarMemoria stuEsperaMemoria;
    unsigned int uiBaseSs0;
}stuPCB;
# 4 "semaforo.c" 2
# 1 "../include/kernel/system.h" 1
# 22 "../include/kernel/system.h"
unsigned long int uliClockTick;





typedef struct
{
    unsigned int :16;
    unsigned int TSSSegmentSelector :16;
    unsigned int :8 ;
    unsigned int Type :5;
    unsigned int DPL :2;
    unsigned int P :1;
    unsigned int :16;
} __attribute__((packed)) t_TaskGate;





typedef struct
{
    unsigned int Offset1 :16;
    unsigned int SegmentSelector :16;
    unsigned int :5 ;
    unsigned int Type :8;
    unsigned int DPL :2;
    unsigned int P :1;
    unsigned int Offset2 :16;
} __attribute__((packed)) t_InterruptGate;




typedef struct
{
    unsigned int Offset1 :16;
    unsigned int SegmentSelector :16;
    unsigned int :5 ;
    unsigned int Type :8;
    unsigned int DPL :2;
    unsigned int P :1;
    unsigned int Offset2 :16;
} __attribute__((packed)) t_TrapGate;




typedef union
{
    t_TaskGate TaskGate;
    t_InterruptGate InterruptGate;
    t_TrapGate TrapGate;
}stuIDTDescriptor;




typedef struct
{
    stuIDTDescriptor IDTDescriptor[256];
} stuIDT;


typedef struct
{
    dword dwLimite :16;
    dword dwBase :32;
} t_IDTRegister;

stuIDT *pstuIDT;
unsigned char ucFnObtenerScanCode();
void vFnIniciarTeclado();
void vFnIniciarExcepciones();
void vFnIniciarIDT();
void vFnHandlerGenerico();
void vFnHandlerTimer();
void vFnPlanificador();
void vFnHandlerTeclado();
void* pvFnKernelStackAdmin();


void vFnHandlerDisquette();

long vFnHandlerSyscall( long eax,
   long ebx,
   long ecx,
   long edx );

void vFnLTR(unsigned int uiSelector);
unsigned int uiFnSTR(void);
# 5 "semaforo.c" 2
# 1 "../include/video.h" 1
# 14 "../include/video.h"
# 1 "../include/kernel/libk/string.h" 1
# 9 "../include/kernel/libk/string.h"
inline unsigned char* ucpFnCopiarMemoria(unsigned char *ucpDestino,
      unsigned char *ucpOrigen,
      unsigned int uiTamanio);
inline unsigned char* ucpFnMemSetCero(unsigned char *ucpDirInicio,
                  unsigned int uiTamanio );

int iFnLongitudCadena (const char *cnstCadena);
int iFnCompararCadenas (const char *, const char *);
int iFnCompararCadenas2 (const char *, const char *);
int iFnCopiaCaracter (char *, const char *);
int iFnCopiaCadena (char *, const char *);

int iFnCopiaEntero (char *, const int);
int iFnCopiaFloat (char *, const float, const int);
int iFnCopiaWord (char *, const word);
int iFnCopiaByte (char *, const byte);
int iFnCopiaHexa (char *, const int);
int iFnCopiaWordHexa (char *, const word);
int iFnCopiaByteHexa (char *, const byte);
void vFnImprimirString (char *, const char *, ...);
int iFnLongitudCadena (const char *);

int iFnCopiaCadena2 (char *, const char *);
char * pstFnConcatenarCadena (char * , char * );
int iFnBuscarEnCadena (char * , char * ,int );
char * pstFnCadenaIzquierda (char * , int );
char * pstFnCadenaDerecha (char * , int );
int iFnEsNumero (char * stCadena);

void vFnStrLwr (char * stCadena);
void vFnStrUpr (char * stCadena);
# 15 "../include/video.h" 2
# 58 "../include/video.h"
typedef char* va_list;
# 100 "../include/video.h"
int iFnImprimirCadenas (int,const char*);




void vFnImprimirEntero (int,const int);




void vFnImprimirFloat (int,const double, const int);




void vFnImprimirHexa (int,const int);




void vFnImprimirWordHexa (int,const word);




void vFnImprimirByteHexa (int,const byte);





void vFnImprimirWin (int,const char*, ... );
void vFnImprimir (const char*, ... );
void vFnImprimirI (const char*, ... );

extern char cFnSysObtenerColor(int);
extern void vFnSysSetearColor(int,char);
extern void vFnSysSetearX(int,int);
extern void vFnSysSetearY(int,int);
extern void vFnClsWin(int);





void vFnImprimirContextSwitch(int color,int pid, char* nombre, int indiceGDT);
void vFnImprimirPrompt();
void vFnImprimirOk(int linea);
void vFnImprimirNOk(int linea);

void vFnImprimirVentana (int hVentana, const char *cnstCadena, ...);






int bTerminalActiva;

void vFnCambiarTerminal(void);
void vFnLog (const char *cnstCadena, ...);

void vFnLogScrollArriba();
void vFnLogScrollAbajo();

void vFnLogScrollMaximo();
void vFnLogScrollMinimo();
void vFnLogBorrar();
# 6 "semaforo.c" 2

extern stuPCB pstuPCB[50];
extern unsigned long ulProcActual;


semaforo semaforosEnElSistema[5];






void vFnInicializarSemaforos()
{
 int pid,i;
 semaforo sem;

 pid=0;
 sem.valor = 0;
 sem.pshared = 0;
 sem.head = 0;
 sem.tail = 0;
 sem.procesosEnCola = 0;

 sem.inicializado = 0;


 for (i=0;i<5;i++)
 {
  sem.cola[i]=pid;
 }

 for (i=0;i<5;i++)
 {
  semaforosEnElSistema[i]=sem;
 }
}






int iFnSemInit(sem_t *sem, int pshared, unsigned int value)
{
 sem = (sem_t*)(pstuPCB[ ulProcActual ].uiDirBase + (unsigned int)sem);

 sem->sem_id = agregarSemaforoAlSistema(pshared,value);

 if(sem->sem_id != -1)
 {
  return 0;
 }
 else
 {
  return -1;
 }
}






int iFnSemClose(sem_t *sem)
{
 int posicion,i;

 sem = (sem_t*)(pstuPCB[ ulProcActual ].uiDirBase + (unsigned int)sem);


 if(validaExistenciaSemaforo(sem) != -1)
 {
  posicion = sem->sem_id;


  for (i=0;i<5;i++)
  {
   while(iFnHayProcesoEnEspera(&semaforosEnElSistema[posicion]))
   {
    unsigned long int procesoADespertar = uliFnDesencolarProceso(&semaforosEnElSistema[posicion]);
    pstuPCB[procesoADespertar].iEstado = 1;
    vFnPlanificador();
   }
   semaforosEnElSistema[posicion].cola[i] = 0;
  }


  semaforosEnElSistema[posicion].valor=0;
  semaforosEnElSistema[posicion].pshared=0;
  semaforosEnElSistema[posicion].inicializado = 0;

  return 0;
 }

 return -1;
}






int iFnHayLugarEnLaCola(semaforo *sem){
 return !(sem->procesosEnCola==5);
}
# 120 "semaforo.c"
int iFnHayProcesoEnEspera(semaforo *sem)
{
 return sem->procesosEnCola>0;
}






unsigned long int uliFnDesencolarProceso(semaforo *sem)
{
 unsigned long retorno;
 retorno = sem->cola[sem->head];
 sem->cola[sem->head] = 0;
 sem->head = (sem->head+1)%5;
 sem->procesosEnCola--;
 return retorno;
}






void vFnEncolarProceso(semaforo *sem, unsigned long int uliId)
{
 sem->cola[sem->tail]=uliId;
 sem->procesosEnCola++;
 sem->tail=(sem->tail+1)%5;
}






int iFnSemWait(sem_t *sem)
{
 sem = (sem_t*)(pstuPCB[ ulProcActual ].uiDirBase + (unsigned int)sem);

 semaforosEnElSistema[sem->sem_id].valor--;
 if(semaforosEnElSistema[sem->sem_id].valor < 0){
  if(iFnHayLugarEnLaCola(&semaforosEnElSistema[sem->sem_id])){
   vFnEncolarProceso(&semaforosEnElSistema[sem->sem_id], pstuPCB[ulProcActual].ulId);
   pstuPCB[ulProcActual].iEstado = 3;
   vFnPlanificador();
  }
  else
  {

   return -1;
  }
 }
 return 0;
}






int iFnSemPost(sem_t *sem)
{
 int i;
 sem = (sem_t*)(pstuPCB[ ulProcActual ].uiDirBase + (unsigned int)sem);


 if(semaforosEnElSistema[sem->sem_id].inicializado==0)
 {
  return -1;
 }

 semaforosEnElSistema[sem->sem_id].valor++;
 if(iFnHayProcesoEnEspera(&semaforosEnElSistema[sem->sem_id]))
 {
  unsigned long int idProcesoADespertar = uliFnDesencolarProceso(&semaforosEnElSistema[sem->sem_id]);
  for(i=0;i<50;i++)
  {
   if(pstuPCB[i].ulId == idProcesoADespertar)
   {
    pstuPCB[i].iEstado = 1;
    vFnPlanificador();
    return 0;
   }
  }
 }

 return -1;
}






int agregarSemaforoAlSistema(int pshared, unsigned int value)
{
 int i;

 for(i=0;i<5;i++)
 {
    if(semaforosEnElSistema[i].inicializado == 0)
    {
     semaforosEnElSistema[i].valor = value;
     semaforosEnElSistema[i].inicializado = 1;
   semaforosEnElSistema[i].pshared = pshared;
   return i;
    }
 }

 return -1;
}






int validaExistenciaSemaforo(sem_t *sem)
{

 if(semaforosEnElSistema[sem->sem_id].inicializado != 0)
  return 0;
 else
  return -1;
}






void vFnVerSemaforos()
{
 int i,j;


 vFnImprimir("\n\nSemaforos del Sistema:\n");
 for (i=0;i<5;i++)
 {
  vFnImprimir("Valor: %d, Pshared: %d, Inicializado: %d, Cola: ",semaforosEnElSistema[i].valor,semaforosEnElSistema[i].pshared,semaforosEnElSistema[i].inicializado);

  for (j=0;j<5;j++){
   vFnImprimir("[%d]",semaforosEnElSistema[i].cola[j]);
  }

  vFnImprimir("\n");
 }
}
